What's new
Hardware h1.2 and software s1.00 (released) http://syam.no-ip.org/stacker_v1.00.zip (07.01.2016) It requires hardware h1.2. This is my ultimate hardware mod - h1.2, and a new software version (s1.00) which makes use of the new hardware capabilities of h1.2. The main improvement is the ability to independently control from Arduino both camera's shutter and autofocus. The hardware changes involved the following (compared to h1.1): * LCD reset pin (RST) disconnected from Arduino (pin 6); instead it is now hardware controlled via RC delay circuit (R=47k, C=0.1uF, connected to VCC=+3.3V). * Arduino pin 6 is now used to control the second relay (+ diod + R=33 Ohm), for camera autofocus. * As there would not be enough of wires in the Cat5/6 cable to add the output of the second relay, significant rearrangements were made: ** The old relay (+ diode + 33R resistor) were moved from the controller unit to the motor unit's breadboard. ** The second relay (+ diode + 33R resistor) were added to the motor unit's breadboard. ** The mono 2.5mm phono socket in the motor unit was upgraded to 3.5mm stereo screw type phono socket. ** In the Yongnuo shutter cable connecting the motor unit to the camera the 2.5 mm stereo jack was replaced with a 3.5mm stereo jack. ** The assignment of some of the 8 wires of the Cat5/5 cable has changed: now wire #1 (white-orange) is directly connected to Arduino pin 3 (camera shutter); wire #2 (orange) is the common ground; wire #3 (white-green) is directly connected to Arduino pin 6 (camera AF); wire #6 (green) is directly connected to Arduino pin 8 (limiters). The motors' four wires (4, 5, 7, 8) stayed unchanged. Software s0.14 (released) http://syam.no-ip.org/stacker_v0.14.zip (25.12.2015) A minor update compared to the previous version (s0.12). Two changes: # A separate (lower) speed limit, SPEED_LIMIT2_MM_S in stacker.h, was introduced. When power up, the controller senses if it is powered by AC or batteries (by using a simple critical voltage criteria: < 11.5V is considered to be battery operated). If it is AC operated, it uses the standard (high) limit - 5 mm/s in my code. If it is battery operated, it uses the slower speed limit - 2.5 mm/s in my code. This will help to improve torque (and eliminate steps skipping by the motor) when battery operated, in the field. If you want to disable this new feature, set the critical voltage parameter (SPEED_VOLTAGE in stacker.h) to a negative number (say, -1). # A bug fix: factory reset was sometimes misbehaving (would drive the rail against the foreground physical limit, and then get stuck there). This was fixed by increasing the value of the parameter DELTA_LIMITER from 400 to 1000, in stacker.h. Software s0.12 (released) http://syam.no-ip.org/stacker_v0.12.zip It requires hardware h1.1 (same as for s0.10). Improvements and changes (compared to s0.10): # I introduced a new mode: non-continuous stacking (only available for 2-point stacking; 1-point stacking can only be done using the continuous stacking mode). Unlike my old continuous stacking mode, in the new (non-continuous) mode the camera doesn't move when taking a shot. There are two new parameters - First_delay and Second_delay - which can be cycled through by pressing "#8" and "#9", respectively. (I had to sacrifice my memory Register 3 to gain these two key bindings.) Non-continuous stacking is initiated by pressing "#0" (the continuous one - by pressing "0"; both modes always start shooting from the foreground point, which eliminates the backlash). The camera moves to the foreground point, then stops and right away the shutter is triggered (this locks the mirror in the camera; the camera should have had the mirror lock enabled). Then it waits for First_delay ("#8") seconds - this lets the vibrations caused by the camera movement and the mirror moving decay, and then the camera shutter is triggered again - this time to initiate the shot. Finally, after Second_delay ("#9") seconds - should be larger than the exposure time - the camera starts moving again, to the next frame position. This mode minimizes rail vibrations caused by the moving rail and the camera mirror, and can be used when the best possible sharpness is required (though my tests show no improvement in sharpness - when using flash at 1/16 power as the light source), or when using a continuous source of light (not a flash). The drawback: this mode is substantially slower, and eats up your camera/rail battery faster. # Related change - now key "#" has a function of its own: as long as it is pressed the fifth line in the LCD will show three numbers related to the non-continuous stacking: First_delay (seconds), Second_delay (seconds), and the estimated non-continuous stacking time (seconds; properly takes into account limited acceleration/deceleration of the rail movements). While pressing "#" one can also press "0" (making it a "#0" key binding) to initiate non-continuous focus stacking with the displayed parameters. # The meaning of "#0" key binding changed: instead of 2-point continuous stacking (always starting from the foreground point) it now triggers 2-point non-continuous stacking, always from the foreground point (which is backlash compensated = accurate). # The meaning of "0" also changed - instead of 2-point stacking from the nearest of the two points, it now starts continuous 2-point stacking always from the foreground point (backlash compensated). # Introduced new macro parameter in stacker.h - MIRROR_LOCK (defined by default). Comment this definition out if you don't want to use the mirror lock feature on your camera when doing non-continuous stacking. (Though it makes much more sense to always use the mirror lock in non-continuous stacking, as the whole point of non-continuous stacking is to minimize camera vibrations while shooting, and mirror contributes a substantial part to the vibrations.) # The "Pause" function (pressing any key while doing 2-point stacking) has been extended to include the new non-continuous stacking mode. Now pressing any key while doing non-continuous 2-point stacking will put the rail in the paused mode, with the same behaviour as the original paused mode - "#1"/"#A" will move the camera back/forward one frame without taking a shot, "1"/"A" will travel 10 frames back/forward, "#7" will take a shot, "#B" will abort stacking, and "0" will resume stacking from the currently displayed frame number. When using MIRROR_LOCK parameter (which is default), putting the rail in the pause mode when the mirror is locked will instantly trigger the camera shutter to unlock the mirror. # As mentioned above, the meaning of "#8" and "#9" key bindings changed - instead of doing save/restore of all rail parameters to custom Register 3, now it cycles through the table of different values for two new non-continuous parameters - First_delay and Second_delay, respectively (seconds). The current tables for these parameters have the following values: 0.2, 0.5, 1, 2, 5, 10 seconds. One can always modify / extend /reduce the tables in stacker.h, by modifying constants FIRST_DELAY, SECOND_DELAY, and the corresponding table length parameters - N_FIRST_DELAY and N_SECOND_DELAY. # I fixed the behaviour of the frame number displayed when in the paused mode - now it displays the number for the last taken frame. As the pause happens somewhere between the last taken shot and the next one, pressing "#1" now (properly) rewinds the rail to the exact position of the last frame, without changing the frame number displayed. Pressing "#1" one more time will rewind one frame back, reducing the frame number displayed. The proper procedure to recover from a problem (e.g. flash battery died) while stacking is to press any key (putting the rail into Paused mode), check your camera for the number of the first failed frame, then rewind the rail with "#1" until the first failed frame number is displayed, and then press "0" to resume stacking from the first failed frame. # I found the line where one can change the contrast of the LCD display - line 234 in pcd8544.cpp, command(PCD8544_VOP | 0x47);. The default value (0x3F) resulted in low contrast on my display. I changed the value to 0x47 which resulted in a much better contrast. Your LCD might need a different value - play with this parameter until you are happy with the result. Hardware h1.1 and software s0.10 (released) http://syam.no-ip.org/stacker_v0.10.zip This is a fairly minor hardware revision (a bit of re-soldering needs to be done, and only inside the controller unit; one additional 10 k resistor is required). Here are the changes, compared to h1.0: * Second row keypad pin (6) moved from Arduino pin 10 to 7. * Pin 10 left free (for hardware SPI). * Display's pin SCE (CE / chip select) disconnected from pin 7. * Instead, display SCE pin is soldered to the ground via ~10k (pulldown) resistor. The reason for the above changes: I finally figured out how to enable hardware SPI connection between the Arduino and the Nokia 5110 LCD display (so far my design have been using the much slower software emulation SPI). I discovered that for this to work the Arduino's pin 10 needs to be freed up, and some small software modifications applied. I managed to gain one extra Arduino pin by using a pulldown resistor on the Nokia's SCE pin. I already did the mod, and it seems to be working as expected. The hardware SPI resulted in ~10 times faster communication between Arduino and LCD, and that in turn resulted in more accurate (in fact, perfectly accurate) rail motions during stacking (the only time when my software updates both the motor and the display states). And here is the list of major improvements and changes in the s0.10 software (requires hardware h1.1 to work), compared to s0.08. # I did a major work with the software profiling - now the Arduino loop became substantially faster, which is critical for accurate rail motions. In particular, I optimized my own code, and also both the LCD and keypad libraries I am using. Because one now needs the custom versions of these libraries, I am providing them along with my code (so no need to install any libraries from now on). In particular, I enabled hardware SPI for 10x faster Arduino-LCD communications in the LCD library, and reduced data dimensions and disabled pin Arduino sharing in the keypad library. # As a part of my profiling I discovered that even with the optimized code my software skips microsteps occasionally (around 0-3 microsteps skipped per 10,000 microsteps travelled), because some Arduino loops are substantially longer than average. This is very minor, but my new software has a module to completely eliminate all step skipping, so from now on the program coordinates always match the physical (rail) coordinates. (This is controlled by the macro parameter PRECISE_STEPPING in stacker.h; it is enabled by default.) Also the next improvement is critical for this. # I fully implemented backlash compensation in my software (constant BACKLASH_MM in stacker.h; set it to 0 to disable backlash compensation). From my measurements, the full backlash of my rail is 0.2mm, and from now on it is going to be fully compensated: every time rail comes to a stop, the required compensation will have been made. This applies to all rail motions - go_to operations, rewinding, stacking etc. This guarantees that the program coordinates always match the physical ones, at least for the situation when it is at rest or is moving in the "good" direction (which is from foreground to background in my software). The only problematic function in this regard is doing 2-point stacking in the "bad" (towards foreground) direction, where backlash is not compensated, so coordinates will not be accurate. Because of this I introduced a new keypad shortcut, "#0" (see below), which always starts 2-point stacking from the foreground point. # As part of my backlash compensation package, I introduced a new module (macro parameter EXTENDED_REWIND in stacker.h; enabled by default). This module makes the rewind function (key "1") emulate the fast-forward key, "A", with full backlash compensation. Specifically, if you say press "A" key for 0.1s, the rail will travel (in the good direction) say 20 um. Now if you press the rewind key "1" for the same time 0.1s, the rail will do a full backlash compensation, and at the end will be 20 um behind. So the same amount of pressing on "1" results in the same amount of traveling as with "A"; the only difference is that after you release "1" it takes longer for the rail to come to a complete stop. This function is very useful when you want to have both high accuracy (full backlash compensation) and convenience when using 1/A keys. # Now I have a fully-functioning "pause" feature. Before, if you pressed any key while stacking was in progress, it would abort the stacking, which wasn't ideal. Now (only for 2-point stacking) pressing any key will place the rail in the special "paused" mode, with most keys disabled, and some changing their meaning. In particular, "#1" and "#A" will now move the rail precisely to the next frame in the fore/background directions (without taking a shot), and "1" and "A" will do the same with larger steps of 10 frames. "#4" and "#7" will still work as usual. Pressing "0" at any time will resume stacking from the current frame, while pressing "#B" will abort the stacking. This should significantly improve handling problems during lengthy stacking, such as dead flash/camera battery or overheated flash. If something like this happens, you just have to press any key to place the rail into the "paused" mode, change the batteries or let the flash cool down, check the camera to see how many frames were wasted (black), then use "#1"/"#A" or "1"/"A" keys to go back to the position of the first failed shot, and then press "0" to resume stacking. # New convenient function added, linked to the keys "#D". This will move the rail back to the starting point of your last stacking (not memorized in EEPROM). Should be convenient for 1-point stacking: you just need to press "#D" to go to the starting point, if you want to redo stacking. Also convenient for 2-point stacking, if you always want to start stacking from the same point (either fore or background). The default behavior (when pressing "0") is to start stacking from the nearest of the two points. Should be used for critical work when you need to precisely reproduce your stacking sequence. # Another new function: "#0". Initiates 2-point stacking (the rail can be anywhere when you press it), but unlike function "0" it always starts from the foreground point, and moves towards the background point when stacking. This direction is "good" in terms of backlash compensation. Use this function to do 2-point stacking when the most accurate and reproducible results are required. # I draw and programmed some nice bitmaps for the display - different levels of the battery charge, and the direction of motion. Before I used two chars of standard ASCII. # Now the software has the ability to have a slower "ramp" (acceleration) when initiating rewind/fast forward (keys "1"/"A"); all other movements will still be done at the maximum acceleration/deceleration level, ACCEL_LIMIT. This should make it easier to fine tune the rail position when setting up the foreground and/or background points for stacking, but still retaining the ability to go to the maximum possible speed fairly quickly (with just a bit more of a delay). Modify the new constant ACCEL_FACTOR in stacker.h to change the ratio between the fast and slow acceleration values (the default ratio is 4). Minor improvements and bug fixes: * Fixed a small dx bug in go_to() * Small code re-arrangements to reduce Arduino loop duration when a starting to move. * Change to the displayed frame counter: now it includes 0. * Another frame counter issue fixed: now when aborting stacking, it reverts to "0". * Some of my recent changes (most likely borrowing the two Arduino pins from LCD control) resulted in the intermediate brightness backlighting crashing the LCD. I fixed that by making my backlighting control to only use two levels - no backlighting, and full backlighting. * Fixed a small bug: backlighting level wasn't memorized when the device is turned off. * Some cosmetic code re-arrangement and cleanup. = Heads up = This is the section to report on what I am working on right now - if you are in the process of reproducing my rail's design, this might be very valuable (so you'll know that e.g. you might consider ordering another part, or if a new feature, very important to you, is in the works right now.) My original hardware has a "hardware version" h1.0. The software supporting this hardware has a version s0.08. (I prepend h and s to differentiate between hardware and software versions.) Hardware v1.2 (future work) My next (and likely final) hardware mod will be as follows: * DONE I need to free up yet another Arduino pin. I just (28/12/15) accomplished an important step towards implementing this hardware upgrade. Specifically, I managed to achieve the initial LCD reset without using Arduino. Instead, I am using an RC delay circuit, with the (pull up) resistor R connecting VCC and RST pins on the LCD, and the capacitor C connecting RST and GND (ground); RST is no longer connected to Arduino. When using C=0.1uF, my LCD works fine for R between 33 kOhm and 680 kOhm. This implies that the delay required for the reset to work is R*C ~ 3 ms. I believe R value should be as small as possible, to minimize the chance of electrical noise messing up with the LCD; I decided to use R=47 kOhm to have some leeway (to account for R changing with temperature and humidity). I already soldered the resistor and the capacitor to the LCD, and will be doing some stability testing before proceeding with the rest of the mod. * Use the Arduino pin I freed up to control a second relay (with additional diode and 33 Ohm resistor), for autofocus camera control. Some software modifications will be required. This will speed up one-point shooting with Canon DSLRs (which do not need AF control to operate), and will make my rail usable for all cameras, including those which require both AF and shutter triggers to make a shot. * As I don't have enough of wires in my Cat-5 cable to prove the AF control to the motor unit using my old approach, I will have to move both relays (the old and the new ones) inside the motor unit. This will allow me to save two wires (one wire - ground - can now be shared between three circuits - limiter switches, shutter trigger, and AF trigger). Unfortunaly that means that only one kind of Cat-5/6 cable can now be used (either straight or crossover.) The new wiring will be: ** 4 wires for motor control (as before); ** 1 wire directly to the limiter switch pin (8) of Arduino; ** 1 wire directly to the shutter control pin (3) of Arduino; ** 1 wire directly to the AF control pin (6) of Arduino. * I will replace my 2-contact (mono) 2.5mm phono socket in the motor unit with a stereo 3.5mm socket (also screw type, for maximum reliability; I already got these from ebay). This will allow for independent control of both shutter and AF in the camera. In my Yongnuo shutter cable, I will replace the 2.5mm stereo jack with 3.5mm stereo jack, to match the new socket.